package com.flying.carclub.http;


import com.flying.carclub.utils.StringUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by xcheng on 2015/9/16.
 */
public class BaseApiHelper  {

    //自定义的请求构造器
    private Builder builder;
    private IOkHttpApi iOkHttpApi;
    public BaseApiHelper() {
        super();
        init(builder);
    }

    public BaseApiHelper(Builder builder) {
        super();
        init(builder);
    }
    private void initOkHttpApi(){
        iOkHttpApi = OkHttpExecutor.instance;
    }
    private void init(Builder builder) {
        initOkHttpApi();
        if (builder == null) {
            builder = new Builder();
        }
        this.builder = builder;
    }


    /**
     * 异步get请求
     * @param requestParams
     * @param apiHandler
     */
    protected void httpGet(OkRequestParams requestParams,ApiHandler apiHandler){
        Request request = iOkHttpApi.buildHttpGetRequest(requestParams);
        sendRequest(apiHandler, null, request,requestParams.getConnectTimeout());
    }
    /**
     * app中异步请求
     * @param requestParams
     * @param apiHandler
     */
    protected void httpPost(OkRequestParams requestParams,ApiHandler apiHandler){
        httpPost(requestParams, apiHandler,null);
    }

    /**
     * app中异步请求
     * @param handler
     * @param url
     * @param nameValuePairs
     */
    protected void httpPost(ApiHandler handler,String url,NameValuePair... nameValuePairs){
        httpPost(handler, null, url, StringUtil.stripNulls(nameValuePairs));
    }

    /**
     * app中同步请求 返回OkHttp的Response
     *
     * @param params
     * @return
     */
    protected Response syncHttpPostReturnResponse(OkRequestParams params){
        Request httpRequestBase = iOkHttpApi.buildHttpPostRequest(params);
        return sendSyncRequestReturnResponse(httpRequestBase,params.getConnectTimeout());
    }


    /**
     * app中同步请求 返回String类型，失败返回null
     * @param params
     * @return
     */
    protected String syncHttpPost(OkRequestParams params){
        Request httpRequestBase = iOkHttpApi.buildHttpPostRequest(params);
        return sendSyncRequest(httpRequestBase,params.getConnectTimeout());
    }


    /**
     * 同步 post String数据
     * 暂时不支持传递参数，要是需要可拼接在url中
     * @param params
     * @return
     */
    protected String syncHttpPostString(OkRequestParams params){
        Request httpRequestBase = iOkHttpApi.buildHttpPostStringRequest(params);
        return sendSyncRequest(httpRequestBase, params.getConnectTimeout());
    }

    /**
     * 异步 post String数据
     * 暂时不支持传递参数，要是需要可拼接在url中
     * @param params
     * @return
     */
    protected void httpPostString(OkRequestParams params,ApiHandler handler){
        Request httpRequestBase = iOkHttpApi.buildHttpPostStringRequest(params);
        sendRequest(handler, null, httpRequestBase,params.getConnectTimeout());
    }


    /**
     * 上传文件
     * @param params
     * @return
     */
    protected String syncHttpPostFile(OkRequestParams params){
        Request httpRequestBase = iOkHttpApi.buildHttpPostFileRequest(params);
        return sendSyncRequest(httpRequestBase, params.getConnectTimeout());
    }





    /**
     * 不带参数
     *
     * @param handler
     * @param parser
     * @param url
     */
    protected void httpGet(ApiHandler handler, BaseParser<?> parser, String url) {
        httpGet(handler, parser, url, new ArrayList<NameValuePair>());
    }


    /**
     * 一个参数的get请求
     *
     * @param handler
     * @param parser
     * @param url
     * @param valuePair
     */
    private void httpGet(ApiHandler handler, BaseParser<?> parser, String url, NameValuePair valuePair) {
        ArrayList<NameValuePair> valuePairs = new ArrayList<>();
        valuePairs.add(valuePair);
        httpGet(handler, parser, url, valuePairs);
    }

    /**
     * 列表参数的httpGet请求
     *
     * @param handler
     * @param parser
     * @param url
     * @param valuePairs
     */
    private void httpGet(ApiHandler handler, BaseParser<?> parser, String url, ArrayList<NameValuePair> valuePairs) {
        Request request = iOkHttpApi.buildHttpGetRequest(url, valuePairs);
        sendRequest(handler, parser, url, request);
    }
    /**
     * 可变参数的httpGet请求
     *
     * @param handler
     * @param parser
     * @param url
     * @param nameValuePairs
     */
    private void httpGet(ApiHandler handler, BaseParser<?> parser, String url, NameValuePair... nameValuePairs) {
        httpGet(handler, parser, url, StringUtil.stripNulls(nameValuePairs));
    }





    private void httpPost(ApiHandler handler,BaseParser<?> parser,String url,NameValuePair... nameValuePairs){
        httpPost(handler, parser, url, StringUtil.stripNulls(nameValuePairs));
    }
    private void httpPost(ApiHandler handler, BaseParser<?> parser, String url, List<NameValuePair> valuePairs) {
        Request httpRequestBase = iOkHttpApi.buildHttpPostRequest(url, valuePairs);
        sendRequest(handler, parser, url, httpRequestBase);
    }
    private void httpPost(ApiHandler handler, BaseParser<?> parser, String url, List<NameValuePair> valuePairs, String cookie) {
        Request httpRequestBase = iOkHttpApi.buildHttpPostRequest(url, valuePairs, cookie);
        sendRequest(handler, parser,url, httpRequestBase);
    }
    private void httpPost(OkRequestParams requestParams,ApiHandler handler, BaseParser<?> parser) {
        Request httpRequestBase = iOkHttpApi.buildHttpPostRequest(requestParams);
        sendRequest(handler, parser, httpRequestBase,requestParams.getConnectTimeout());
    }


    protected String syncHttpPost(String url,  String cookie,NameValuePair... valuePairs){
        Request httpRequestBase = iOkHttpApi.buildHttpPostRequest(url, StringUtil.stripNulls(valuePairs), cookie);
        return sendSyncRequest(httpRequestBase);
    }

    protected String syncHttpPostMap(String url,String cookie,  Map<String,String> valuePairs){
        Request httpRequestBase = iOkHttpApi.buildHttpPostRequest(url, mapToArrayList(valuePairs), cookie);
        return sendSyncRequest(httpRequestBase);
    }

    /**
     * 对接老代码用
     * @param url
     * @param cookie
     * @param valuePairs
     * @return
     */
    protected Response syncHttpPostReturnResponse(String url, String cookie, Map<String,String> valuePairs){
        Request httpRequestBase = iOkHttpApi.buildHttpPostRequest(url, mapToArrayList(valuePairs), cookie);
        return sendSyncRequestReturnResponse(httpRequestBase,0);
    }
    protected Response syncHttpPostReturnResponse(String url, String cookie , NameValuePair... valuePairs){
        Request httpRequestBase = iOkHttpApi.buildHttpPostRequest(url, StringUtil.stripNulls(valuePairs), cookie);
        return sendSyncRequestReturnResponse(httpRequestBase,0);
    }




    private String sendSyncRequest(Request request){
        return sendSyncRequest(request, 0);
    }
    private String sendSyncRequest(Request request, int timeOut) {
        try {
            ApiHandleParams apiHandleParams = new ApiHandleParams();
            apiHandleParams.setRequest(request);
            if (timeOut>0) {
                apiHandleParams.setConnectTimeOut(timeOut);
            }
            apiHandleParams.setToken(builder.token);
            return iOkHttpApi.executeHttpSyncRequest(apiHandleParams);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private Response sendSyncRequestReturnResponse(Request request, int timeOut) {
        try {
            ApiHandleParams apiHandleParams = new ApiHandleParams();
            apiHandleParams.setRequest(request);
            apiHandleParams.setToken(builder.token);
            if (timeOut>0){
                apiHandleParams.setConnectTimeOut(timeOut);
            }
            return iOkHttpApi.executeHttpSyncRequestReturnResponse(apiHandleParams);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * send network request
     *
     * @param handler
     * @param parser
     * @param request
     * @param timeOut
     */
    private void sendRequest(ApiHandler handler, BaseParser<?> parser, Request request, int timeOut) {
        final ApiHandleParams apiHandleParams = new ApiHandleParams();
        apiHandleParams.setApiHandler(handler);
        apiHandleParams.setParser(parser);
        apiHandleParams.setRequest(request);
        apiHandleParams.setConnectTimeOut(timeOut);
        apiHandleParams.setToken(builder.token);
        try {
            /*if (builder.reloadWhenLoadingLayoutClicked && builder.loadingLayouts != null) {
                for (final DxlBaseLoadingLayout loadingLayout : builder.loadingLayouts) {
                    if (loadingLayout != null && loadingLayout.getReLoadClickListener() == null) {
                        loadingLayout.setOnReLoadClickListener(new OnReLoadClickListener() {
                            @Override
                            public void reLoadData() {
                                loadingLayout.showProgress();
                                executeSender(apiHandleParams);
                            }
                        });
                    }
                }
            }
            if (builder.loadingLayouts != null) {
                for (DxlBaseLoadingLayout loadingLayout : builder.loadingLayouts) {
                    if (loadingLayout != null) {
                        loadingLayout.showProgress();
                    }
                }
            }*/
            executeSender(apiHandleParams);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * send network request
     *
     * @param handler
     * @param parser
     * @param url
     * @param request
     */
    private void sendRequest(ApiHandler handler, BaseParser<?> parser, String url, Request request) {
        final ApiHandleParams apiHandleParams = new ApiHandleParams();
        apiHandleParams.setApiHandler(handler);
        apiHandleParams.setParser(parser);
        apiHandleParams.setRequest(request);
        apiHandleParams.setToken(builder.token);
        try {
            /*if (builder.reloadWhenLoadingLayoutClicked && builder.loadingLayouts != null) {
                for (final DxlBaseLoadingLayout loadingLayout : builder.loadingLayouts) {
                    if (loadingLayout != null && loadingLayout.getReLoadClickListener() == null) {
                        loadingLayout.setOnReLoadClickListener(new OnReLoadClickListener() {
                            @Override
                            public void reLoadData() {
                                loadingLayout.showProgress();
                                executeSender(apiHandleParams);
                            }
                        });
                    }
                }
            }
            if (builder.loadingLayouts != null) {
                for (DxlBaseLoadingLayout loadingLayout : builder.loadingLayouts) {
                    if (loadingLayout != null) {
                        loadingLayout.showProgress();
                    }
                }
            }*/
            executeSender(apiHandleParams);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * execute http request
     *
     * @param handleTask
     */
    public void executeSender(ApiHandleParams handleTask) {
        try {
            iOkHttpApi.executeHttpRequest(handleTask);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private List<NameValuePair> mapToArrayList(Map<String,String> valuePairs){
        List<NameValuePair> pairs = new ArrayList<>();
        for (Map.Entry<String,String> entry:valuePairs.entrySet()) {
            NameValuePair nameValuePair = new BasicNameValuePair(entry.getKey(), entry.getValue());
            pairs.add(nameValuePair);
        }
        return pairs;
    }

    public static class Builder {
        // 是否使用模拟数据
        boolean useSimulatedData = false;
        String token;
        // 是否Toast弹出错误提示
        boolean showError;
        // 是否只使用缓存数据
        boolean useCacheOnly = false;
        // 是否缓存该服务响应数据
        boolean cacheResopnse = false;
        // 是否在响应中返回httpRespones对象
        boolean useHttpRespones = false;
        //是否可以重新加载，默认是可以
        boolean reloadWhenLoadingLayoutClicked = true;

        //服务对应的加载遮罩布局
//        ArrayList<DxlBaseLoadingLayout> loadingLayouts = new ArrayList<>();

        public Builder() {
            super();
            //生成服务唯一的令牌
            token = UUID.randomUUID().toString();
        }

        public Builder _useSimulatedData() {
            this.useSimulatedData = true;
            return this;
        }

        /**
         * 是否在响应中添加httpRespones对象
         *
         * @param useHttpRespones
         * @return
         */
        public Builder _useHttpRespones(boolean useHttpRespones) {
            this.useHttpRespones = useHttpRespones;
            return this;
        }

        /**
         * 开启该策略：无网络或加载失败显示失败布局时，点击重新加载数据。
         *
         * @return
         */
        public Builder _reloadStrategy(boolean allowReload) {
            this.reloadWhenLoadingLayoutClicked = allowReload;
            return this;
        }

        /**
         * 只使用缓存数据
         *
         * @param useCacheOnly
         * @return
         */
        public Builder _useCacheOnly(boolean useCacheOnly) {
            if (useCacheOnly) {
                this.cacheResopnse = true;
            }
            this.useCacheOnly = useCacheOnly;
            return this;
        }

        /**
         * 缓存该服务响应数据
         *
         * @return
         */
        public Builder _cacheResponse() {
            this.cacheResopnse = true;
            return this;
        }

        /*
         * 关联加载遮罩
         *
         * @param loadingLayout
         * @return
         */
        /*public Builder _withLoadingLayout(DxlBaseLoadingLayout... loadingLayout) {
            if (loadingLayout != null) {
                for (DxlBaseLoadingLayout dxlBaseLoadingLayout : loadingLayout) {
                    if (dxlBaseLoadingLayout != null) {
                        loadingLayouts.add(dxlBaseLoadingLayout);
                    }
                }
            }
            return this;
        }*/

        /**
         * 构造请求
         *
         * @return
         */
        public Builder _build() {
            return this;
        }

    }

}
